"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.NestFactory = void 0;
const constant_1 = require("./constant");
const express_1 = __importDefault(require("express"));
const body_parser_1 = __importDefault(require("body-parser"));
class NestFactoryStatic {
    create(module) {
        const metadata = Reflect.getMetadata(constant_1.MODULE, module);
        if (metadata) {
            const routes = this.getRouts(metadata);
            if (routes.length > 0) {
                const app = (0, express_1.default)();
                app.use(body_parser_1.default.json());
                app.use(body_parser_1.default.raw());
                app.use(body_parser_1.default.urlencoded({ extended: false }));
                routes.forEach((route) => {
                    const { path, method, fn } = route;
                    app[method](path, fn);
                });
                app.listen(3000, () => {
                    console.log('服务已经启动');
                });
            }
        }
    }
    createRouterMethod(object, key) {
        return (req, res) => {
            const target = object.prototype;
            const params = Reflect.getMetadata('design:paramtypes', target, key);
            const method = target[key];
            const args = [];
            if (params && params.length > 0) {
                // 带参数的
                const property = Reflect.getMetadata(constant_1.PROPERTY, target, key);
                for (let i = 0; i < property.length; i++) {
                    const { type, index, Validate } = property[i];
                    const value = req[type];
                    if (Validate) {
                        try {
                            new Validate().transform(value, params[index].prototype);
                        }
                        catch (err) {
                            res.send(err);
                            return;
                        }
                    }
                    const instance = new params[index];
                    Object.keys(value).forEach((key) => {
                        instance[key] = value[key];
                    });
                    args[index] = instance;
                }
            }
            const objectParams = Reflect.getMetadata('design:paramtypes', object);
            let objectArgs = [];
            if (objectParams) {
                objectArgs = objectParams.map((p) => {
                    return new p();
                });
            }
            const instance = new object(...objectArgs);
            const v = method.apply(instance, args);
            res.send(v);
        };
    }
    getRouts(metadata) {
        const { imports, controllers } = metadata;
        const routes = [];
        if (controllers) {
            controllers.forEach((controller) => {
                const controllerPath = Reflect.getMetadata(constant_1.CONTROLLER, controller);
                Object.getOwnPropertyNames(controller.prototype).forEach((key) => {
                    if (typeof controller.prototype[key] === 'function' && key !== 'constructor') {
                        const path = Reflect.getMetadata(constant_1.ROUTER_PATH, controller.prototype, key);
                        const method = Reflect.getMetadata(constant_1.ROUTER_METHOD, controller.prototype, key);
                        routes.push({
                            path: `/${controllerPath}/${path}`,
                            method,
                            fn: this.createRouterMethod(controller, key)
                        });
                    }
                });
            });
        }
        if (imports) {
            imports.forEach((module) => {
                const metadata = Reflect.getMetadata(constant_1.MODULE, module);
                metadata && routes.push(this.getRouts(metadata));
            });
        }
        return routes;
    }
}
exports.NestFactory = new NestFactoryStatic();
